package com.wimcorp.magic.client.input;

import java.rmi.RemoteException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.fusesource.jansi.Ansi.Color;

import com.wimcorp.magic.client.CommandLineInterface;
import com.wimcorp.magic.exception.ManaException;
import com.wimcorp.magic.exception.SystemException;

public class OrderCardsSelector extends Selector implements Callable<Long[]> {

	private String message;
	private long[] input;
	private Set<Long> inputSet = new HashSet<>();

	public OrderCardsSelector(CommandLineInterface commandLineInterface, String message, long[] input) {
		super(commandLineInterface);
		this.message = message;
		this.input = input;
		for (long i : input) {
			inputSet.add(i);
		}
	}

	@Override
	public Long[] call() throws Exception {
		Set<Long> inputSet = new HashSet<>();
		for (long i : input) {
			inputSet.add(i);
		}
		return order(message, inputSet);
	}

	private Long[] order(String message, Set<Long> inputSet) {
		Options options = getOrderInputOptions();
		Long[] result = new Long[inputSet.size()];
		CommandLineParser parser = new DefaultParser();
		ConsoleInput selectConsole = new ConsoleInput();
		setRun(true);
		while (isRun()) {
			getCommandLineInterface().getMainConsole().cancel();
			getCommandLineInterface().printInstruction(message);
			try {
				CommandLine line = parser.parse(options, selectConsole.readLine().split(" "));
				for (Option option : line.getOptions()) {
					if ("o".equals(option.getOpt())) {
						result = execute(option);
					}
				}
				processCommands(options, line.getOptions());
			} catch (Exception e) {
				getCommandLineInterface().print(e.getMessage(), Color.RED);
			}
		}
		return result;
	}

	private Long[] execute(Option option) throws RemoteException, SystemException, ManaException {
		Long[] result = null;
		String userInput = option.getValue();
		String[] split = userInput.split(",");
		Set<Long> userInputSet = new HashSet<>();
		for (String i : split) {
			userInputSet.add(new Long(i));
		}
		if (userInputSet.size() == inputSet.size()) {
			for (Long l : userInputSet) {
				if (!inputSet.contains(l)) {
					throw new SystemException("Input " + l + "was not found " + inputSet.toArray() + ". ");
				}
			}
		} else {
			throw new SystemException("Not all input was found " + userInputSet.toArray() + ". ");
		}
		setRun(false);
		return result;
	}
	
	public Options getOrderInputOptions() {
		Options options = new Options();
		options.addOption(getHelpOption());
		options.addOption(getOrderInputOption());
		options.addOption(getPlayerListOption());
		options.addOption(getViewBattleFieldOption());
		options.addOption(getViewGraveyardOption());
		options.addOption(getViewHandOption());
		options.addOption(getViewLifeOption());
		return options;
	}

}
